package actor.route

import akka.actor.{Actor, ActorLogging, ActorSystem, Props}
import akka.routing.FromConfig
import com.typesafe.config.ConfigFactory

import scala.annotation.tailrec

/**
 * @Description: TODO
 * @Author: DJJ
 * @Date: 2019/12/18 19:59
 */
object FibonacciRoutee {
  sealed trait Routee
  case class FibonacciNumber(nbr: Int) extends Routee
  def props = Props[FibonacciRoutee]
}
class FibonacciRoutee extends Actor with ActorLogging {
  import FibonacciRoutee._

  override def receive: Receive = {
    case FibonacciNumber(nbr) =>
      val answer = fibonacci(nbr)
      log.info(s"${self.path.name}'s answer: Fibonacci($nbr)=$answer")
  }
  private def fibonacci(n: Int): Int = {
    @tailrec
    def fib(n: Int, b: Int, a: Int): Int = n match {
      case 0 => a
      case _ =>
        fib(n - 1, a + b, b)
    }
    fib(n, 1, 0)
  }
}

/**
 * Router-Pool 模式
 */
object RouterDemo extends App {
  import FibonacciRoutee._
  val routingSystem = ActorSystem("routingSystem",ConfigFactory.load("fibonacciRoutee"))
  val router = routingSystem.actorOf(
    FromConfig.props(FibonacciRoutee.props)
    ,"balance-pool-router")

  router ! FibonacciNumber(10)
  router ! FibonacciNumber(13)
  router ! FibonacciNumber(15)
  router ! FibonacciNumber(17)

  scala.io.StdIn.readLine()

  routingSystem.terminate()

}
